var fs = require('fs');
var path = require('path');

function travelSeq(dir, callback, dirCallback, finish) {
    fs.readdir(dir, function (err, files) {
        (function next(i) {
            if (i < files.length) {

                var name = files[i];
                var pathname = path.join(dir, name);

                fs.stat(pathname, function (err, stats) {
                    if (stats.isDirectory()) {
                        dirCallback(name, function(){
                            travelSeq(pathname, 
                            function(n, next){
                                callback(path.join(name,n), next);
                            }, function(n, next){
                                dirCallback(path.join(name,n), next);
                            }, function () {
                                next(i + 1);
                            });
                        });
                        
                    } else {
                        callback(name, function () {
                            next(i + 1);
                        });
                    }
                });
            } else {
                finish && finish();
            }
        }(0));
    });
}


var CountDown = function(count, callback){
    this.down = function(){
        if(!--count) callback();
    }
}

function travel(dir, callback, dirCallback, finish) {
    fs.readdir(dir, function (err, files) {
        
        var countDown = new CountDown(files.length, function(){
            finish && finish();
        });

        files.forEach(function(name){
            var pathname = path.join(dir, name);

            fs.stat(pathname, function (err, stats) {
                if (stats.isDirectory()) {
                    dirCallback(name, function () {
                       travel(pathname, 
                        function(n,next){
                            callback(path.join(name,n), next);
                        }, 
                        function(n,next){
                            dirCallback(path.join(name,n), next);
                        }, 
                        function () {
                            countDown.down();
                        });
                    });
                } else {
                    callback(name, function () {
                        countDown.down();
                    });
                }
            });
        });
    });
}

//并发复制
exports.copy = function(src, dest, callback){
    
    fs.exists(dest, function(exist){
        if(exist){
            doCopy();
        } else {
            fs.mkdir(dest,doCopy);
        }
    });

    function doCopy(){
        travel(src, function(name, callback){
            fs.createReadStream(path.join(src,name)).pipe(fs.createWriteStream(path.join(dest, name))).on('finish',function(){
                callback();
            });
        }, function(name, callback){
            fs.mkdir(path.join(dest,name), function(){
                callback();
            });
        },callback);
    }
    
};

//串行复制
exports.copySeq = function(src, dest, callback){
    if (!fs.existsSync(src)) {
        callback("源目录/文件:" + src + "不存在，拷贝失败！",null);
        return;
    }
    
    fs.exists(dest, function(exist){
        if(exist){
            doCopy();
        } else {
            fs.mkdir(dest,doCopy);
        }
    });

    function doCopy(){
        travelSeq(src, function(name, next){
            fs.createReadStream(path.join(src, name)).pipe(fs.createWriteStream(path.join(dest,name))).on('finish', function(){
                next();
            });
        }, function(name, next){
            fs.mkdir(path.join(dest,name), function(){
                next();
            });
        },callback);
    }
    
};